package com.xinbochuang.machine.admin.service.impl.system;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinbochuang.machine.admin.domain.system.SysRole;
import com.xinbochuang.machine.admin.domain.system.SysUser;
import com.xinbochuang.machine.admin.domain.system.SysUserRole;
import com.xinbochuang.machine.admin.mapper.system.SysRoleMapper;
import com.xinbochuang.machine.admin.mapper.system.SysUserMapper;
import com.xinbochuang.machine.admin.service.system.ISysRoleService;
import com.xinbochuang.machine.admin.service.system.ISysUserRoleService;
import com.xinbochuang.machine.admin.service.system.ISysUserService;
import com.xinbochuang.machine.common.annotation.DataScope;
import com.xinbochuang.machine.common.constant.UserConstants;
import com.xinbochuang.machine.common.enums.UserStatus;
import com.xinbochuang.machine.common.exception.CustomException;
import com.xinbochuang.machine.common.utils.SecurityUtils;
import com.xinbochuang.machine.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 黄晓鹏
 * @date 2020-09-08
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private ISysUserRoleService sysUserRoleService;

    @Resource
    private SysUserMapper userMapper;

    @Resource
    private SysRoleMapper roleMapper;

    @Resource
    private ISysRoleService roleService;

    /**
     * 查询用户分页列表
     *
     * @param user 用户对象
     * @return 表格数据
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUserList(SysUser user) {
        List<SysUser> list = userMapper.selectUserList(user);
        for (SysUser sysUser : list) {
            if (!SysUser.isAdmin(sysUser.getUserId())) {
                List<String> roleIds = roleService.selectRoleListByUserId(sysUser.getUserId());
                if (!roleIds.isEmpty()) {
                    List<SysRole> roles = roleService.list(new QueryWrapper<SysRole>().lambda().in(SysRole::getRoleId, roleIds));
                    sysUser.setRoles(roles);
                }
            }
        }
        return list;
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param username 用户名称
     * @return 结果
     */
    @Override
    public String checkUserNameUnique(String username) {
        int count = count(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username).last("and rownum = 1"));
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验手机号码是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public String checkPhoneUnique(SysUser user) {
        SysUser info = getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, user.getPhone()).last("and rownum = 1"));
        return isUnique(checkUserId(user), info);
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public String checkEmailUnique(SysUser user) {
        SysUser info = getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getEmail, user.getEmail()).last("and rownum = 1"));
        return isUnique(checkUserId(user), info);
    }

    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(SysUser user) {
        SysUser info = getById(user.getUserId());
        if (StringUtils.isNotNull(info.getUsername()) && info.isAdmin()) {
            throw new CustomException("不允许操作超级管理员用户");
        }
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    @Override
    public boolean deleteUserByIds(Integer[] userIds) {
        List<SysUser> list = new ArrayList<>();
        for (Integer userId : userIds) {
            SysUser user = new SysUser(userId);
            checkUserAllowed(user);
            user.setDelFlag(UserStatus.DELETED.getCode());
            list.add(user);
        }
        //假删除
        return updateBatchById(list);
    }

    /**
     * 新增用户
     *
     * @param user 用户
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertUser(SysUser user) {
        save(user);
        return insertUserRole(user);
    }

    /**
     * 修改用户
     *
     * @param user 用户
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(SysUser user) {
        //删除用户角色关联
        sysUserRoleService.remove(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, user.getUserId()));
        //添加用户角色关联
        insertUserRole(user);
        if (StrUtil.isNotBlank(user.getPassword())) {
            user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        } else {
            user.setPassword(null);
        }
        return updateById(user);
    }

    /**
     * 查询用户所属角色组
     *
     * @param username 用户名
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(String username) {
        List<SysRole> list = roleMapper.selectRolesByUserName(username);
        StringBuilder idsStr = new StringBuilder();
        for (SysRole role : list) {
            idsStr.append(role.getRoleName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    /**
     * 根据用户id获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @Override
    public SysUser info(Integer userId) {
        SysUser user = userMapper.selectUserById(userId);
        List<String> roleIds = roleMapper.selectRoleListByUserId(userId);
        if (!roleIds.isEmpty()) {
            user.setRoleIds(Convert.toIntArray(roleIds));
        }
        return user;
    }

    /**
     * 根据条件查询用户
     *
     * @param user 条件信息
     * @return 用户集合
     */
    @Override
    public List<SysUser> selectByParams(SysUser user) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getDelFlag, 0);
        if (user != null) {
            //账号名
            if (StrUtil.isNotBlank(user.getUsername())) {
                queryWrapper.lambda().like(SysUser::getUsername, user.getUsername());
            }
            //昵称
            if (StrUtil.isNotBlank(user.getNickname())) {
                queryWrapper.lambda().like(SysUser::getNickname, user.getNickname());
            }
            //部门
            if (user.getDeptId() != null) {
                queryWrapper.lambda().eq(SysUser::getDeptId, user.getDeptId());
            }
            //手机号
            if (StrUtil.isNotBlank(user.getPhone())) {
                queryWrapper.lambda().like(SysUser::getPhone, user.getPhone());
            }
            //身份证号
            if (StrUtil.isNotBlank(user.getIdCard())) {
                queryWrapper.lambda().like(SysUser::getIdCard, user.getIdCard());
            }
        }
        return list(queryWrapper);
    }

    /**
     * 校验身份证号码是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public String checkIdCardUnique(SysUser user) {
        SysUser info = getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getIdCard, user.getIdCard()).last("and rownum = 1"));
        return isUnique(checkUserId(user), info);
    }

    /**
     * 新增用户角色关系表
     *
     * @param user 用户
     * @return 结果
     */
    private boolean insertUserRole(SysUser user) {
        if (user.getRoleIds() == null || user.getRoleIds().length == 0) {
            return true;
        }
        List<SysUserRole> list = new ArrayList<>();
        for (Integer roleId : user.getRoleIds()) {
            SysUserRole ur = new SysUserRole();
            ur.setRoleId(roleId);
            ur.setUserId(user.getUserId());
            list.add(ur);
        }
        return sysUserRoleService.saveBatch(list);
    }

    /**
     * 用户ID检测，空返回-1
     *
     * @param user 用户
     * @return 用户ID
     */
    private Integer checkUserId(SysUser user) {
        return StringUtils.isNull(user.getUserId()) ? -1 : user.getUserId();
    }

    /**
     * 判断用户ID是否唯一
     *
     * @param userId 用户ID
     * @param info   用户
     * @return 唯一标识
     */
    private String isUnique(Integer userId, SysUser info) {
        if (StringUtils.isNotNull(info) && !userId.equals(info.getUserId())) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
}
